package com.health.healthproject.util;

import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.MediaType;
import org.springframework.util.MimeTypeUtils;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

public class FileUploadUtil {

    private static String basePath;

    public static void setBasePath(String path) {
        basePath = path;
    }

    // 业务类型枚举
    public enum BusinessType {
        ANNOUNCEMENT("announcement"),
        USER_INFO("user_info");

        private final String folder;

        BusinessType(String folder) {
            this.folder = folder;
        }

        public String getFolder() {
            return folder;
        }
    }

    /**
     * 上传多个文件
     * @param files 文件列表
     * @param type 业务类型
     * @return 上传成功的文件路径列表
     * @throws IOException 如果文件上传过程中发生IO异常
     */
    public static List<String> uploadFiles(List<MultipartFile> files, BusinessType type) throws IOException {
        List<String> uploadedPaths = new ArrayList<>();
        for (MultipartFile file : files) {
            String path = uploadFile(file, type);
            if (path != null) {
                uploadedPaths.add(path);
            }
        }
        return uploadedPaths;
    }

    /**
     * 上传单个文件
     * @param file 文件
     * @param type 业务类型
     * @return 上传成功的文件路径，如果上传失败返回null
     * @throws IOException 如果文件上传过程中发生IO异常
     */
    public static String uploadFile(MultipartFile file, BusinessType type) throws IOException {
        if (file.isEmpty()) {
            return null;
        }

        // 生成文件存储路径
        String fileName = file.getOriginalFilename();
        String fileExtension = getFileExtension(fileName);
        String newFileName = UUID.randomUUID().toString() + fileExtension;
        String datePath = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/"));
        String relativePath = type.getFolder() + "/" + datePath + newFileName;
        Path path = Paths.get(basePath, relativePath);

        // 确保目录存在
        Files.createDirectories(path.getParent());

        // 保存文件
        Files.copy(file.getInputStream(), path);

        return relativePath;
    }

    /**
     * 获取文件扩展名
     * @param fileName 文件名
     * @return 文件扩展名（包括点号）
     */
    /**
     * 获取文件资源
     * @param relativePath 文件相对路径
     * @return 文件资源
     * @throws IOException 如果文件不存在或无法访问
     */
    public static Resource getFileResource(String relativePath) throws IOException {
        Path filePath = Paths.get(basePath, relativePath);
        Resource resource = new UrlResource(filePath.toUri());

        if (resource.exists() && resource.isReadable()) {
            return resource;
        } else {
            throw new IOException("文件不存在或无法访问: " + relativePath);
        }
    }

    /**
     * 获取文件的MediaType
     * @param fileName 文件名
     * @return 文件的MediaType
     */
    public static MediaType getMediaType(String fileName) {
        String extension = getFileExtension(fileName).toLowerCase();
        switch (extension) {
            case ".pdf":
                return MediaType.APPLICATION_PDF;
            case ".png":
                return MediaType.IMAGE_PNG;
            case ".jpg":
            case ".jpeg":
                return MediaType.IMAGE_JPEG;
            case ".gif":
                return MediaType.IMAGE_GIF;
            case ".txt":
                return MediaType.TEXT_PLAIN;
            case ".doc":
            case ".docx":
                return MediaType.parseMediaType("application/msword");
            case ".xls":
            case ".xlsx":
                return MediaType.parseMediaType("application/vnd.ms-excel");
            case ".zip":
                return MediaType.parseMediaType("application/zip");
            default:
                return MediaType.APPLICATION_OCTET_STREAM;
        }
    }

    /**
     * 检查文件是否存在
     * @param relativePath 文件相对路径
     * @return 文件是否存在
     */
    public static boolean exists(String relativePath) {
        Path filePath = Paths.get(basePath, relativePath);
        return Files.exists(filePath);
    }

    private static String getFileExtension(String fileName) {
        if (fileName == null || fileName.lastIndexOf(".") == -1) {
            return "";
        }
        return fileName.substring(fileName.lastIndexOf("."));
    }

    public static boolean download(HttpServletResponse response, String fileName, String newName){
        File file = new File(fileName);
        try {
            //将文件放入输入流
            FileInputStream fis = new FileInputStream(file);
            //设置下载头信息，newName为文件的新下载名。
            response.setContentType("application/force-download");
            response.addHeader("Content-disposition", "attachment;fileName=" + newName);
            //获取response的输出流
            ServletOutputStream os = response.getOutputStream();
            byte[] bytes = new byte[1024];
            int len = 0;
            //文件传输
            while ((len = fis.read(bytes)) != -1){
                os.write(bytes,0,len);
            }
            //关闭流
            fis.close();
            os.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
}